package com.xiyuan.smartutils;

import com.xiyuan.smartutils.constants.SignConstants;
import com.xiyuan.smartutils.reflect.Reflect;
import com.xiyuan.smartutils.reflect.Unsafe;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Function;
import java.util.function.Supplier;

import static com.xiyuan.smartutils.Arrays.get;
import static com.xiyuan.smartutils.Arrays.isEmpty;

/**
 * 对象相关工具类
 *
 * @version v1.0.0 @author lgz 2017-8-27 新建与整理
 */

@SuppressWarnings({"all"})
public final class Objects implements SignConstants {
    private static final String shi = "是";
    
    static {
        Unsafe.init();
    }
    
    /**
     * 将Object转为String<br>
     * 策略为：
     * <pre>
     *  1、null转为"null"
     *  2、调用Convert.toStr(Object)转换
     * </pre>
     *
     * @param obj Bean对象
     * @return Bean所有字段转为Map后的字符串
     */
    public static String toString(Object obj) {
        if (null == obj) {
            return StrUtils.NULL;
        }
        if (obj instanceof Map) {
            return obj.toString();
        }
        
        // return Convert.toStr(obj);
        return String.valueOf(obj);
    }
    
    /**
     * 如果给定对象为{@code null}返回默认值
     *
     * <pre>
     * ObjectUtil.defaultIfNull(null, null)      = null
     * ObjectUtil.defaultIfNull(null, "")        = ""
     * ObjectUtil.defaultIfNull(null, "zz")      = "zz"
     * ObjectUtil.defaultIfNull("abc", *)        = "abc"
     * ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
     * </pre>
     *
     * @param <T>          对象类型
     * @param object       被检查对象，可能为{@code null}
     * @param defaultValue 被检查对象为{@code null}返回的默认值，可以为{@code null}
     * @return 被检查对象为{@code null}返回默认值，否则返回原值
     */
    public static <T> T defaultIfNull(final T object, final T defaultValue) {
        return isNull(object) ? defaultValue : object;
    }
    
    /**
     * 如果被检查对象为 {@code null}， 返回默认值（由 defaultValueSupplier 提供）；否则直接返回
     *
     * @param source               被检查对象
     * @param defaultValueSupplier 默认值提供者
     * @param <T>                  对象类型
     * @return 被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @throws NullPointerException {@code defaultValueSupplier == null} 时，抛出
     */
    public static <T> T defaultIfNull(T source, Supplier<? extends T> defaultValueSupplier) {
        if (isNull(source)) {
            return defaultValueSupplier.get();
        }
        return source;
    }
    
    /**
     * 如果被检查对象为 {@code null}， 返回默认值（由 defaultValueSupplier 提供）；否则直接返回
     *
     * @param source               被检查对象
     * @param defaultValueSupplier 默认值提供者
     * @param <T>                  对象类型
     * @return 被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @throws NullPointerException {@code defaultValueSupplier == null} 时，抛出
     */
    public static <T> T defaultIfNull(T source, Function<T, ? extends T> defaultValueSupplier) {
        if (isNull(source)) {
            return defaultValueSupplier.apply(null);
        }
        return source;
    }
    
    
    /**
     * 如果给定对象为{@code null}或者""返回默认值, 否则返回自定义handle处理后的返回值
     *
     * @param str          String 类型
     * @param handle       自定义的处理方法
     * @param defaultValue 默认为空的返回值
     * @param <T>          被检查对象为{@code null}或者 ""返回默认值，否则返回自定义handle处理后的返回值
     * @return 处理后的返回值
     * @deprecated 当str为{@code null}时，handle使用了str相关的方法引用会导致空指针问题
     */
    @Deprecated
    public static <T> T defaultIfEmpty(String str, Supplier<? extends T> handle, final T defaultValue) {
        if (StrUtils.isNotEmpty(str)) {
            return handle.get();
        }
        return defaultValue;
    }
    
    /**
     * 如果给定对象为{@code null}或者""返回默认值, 否则返回自定义handle处理后的返回值
     *
     * @param str          String 类型
     * @param handle       自定义的处理方法
     * @param defaultValue 默认为空的返回值
     * @param <T>          被检查对象为{@code null}或者 ""返回默认值，否则返回自定义handle处理后的返回值
     * @return 处理后的返回值
     */
    public static <T> T defaultIfEmpty(String str, Function<CharSequence, ? extends T> handle, final T defaultValue) {
        if (StrUtils.isNotEmpty(str)) {
            return handle.apply(str);
        }
        return defaultValue;
    }
    
    /**
     * 如果给定对象为{@code null}或者 "" 返回默认值
     *
     * <pre>
     * ObjectUtil.defaultIfEmpty(null, null)      = null
     * ObjectUtil.defaultIfEmpty(null, "")        = ""
     * ObjectUtil.defaultIfEmpty("", "zz")      = "zz"
     * ObjectUtil.defaultIfEmpty(" ", "zz")      = " "
     * ObjectUtil.defaultIfEmpty("abc", *)        = "abc"
     * </pre>
     *
     * @param <T>          对象类型（必须实现CharSequence接口）
     * @param str          被检查对象，可能为{@code null}
     * @param defaultValue 被检查对象为{@code null}或者 ""返回的默认值，可以为{@code null}或者 ""
     * @return 被检查对象为{@code null}或者 ""返回默认值，否则返回原值
     */
    public static <T extends CharSequence> T defaultIfEmpty(final T str, final T defaultValue) {
        return StrUtils.isEmpty(str) ? defaultValue : str;
    }
    
    /**
     * 如果被检查对象为 {@code null} 或 "" 时，返回默认值（由 defaultValueSupplier 提供）；否则直接返回
     *
     * @param str                  被检查对象
     * @param defaultValueSupplier 默认值提供者
     * @param <T>                  对象类型（必须实现CharSequence接口）
     * @return 被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @throws NullPointerException {@code defaultValueSupplier == null} 时，抛出
     */
    public static <T extends CharSequence> T defaultIfEmpty(T str, Supplier<? extends T> defaultValueSupplier) {
        if (StrUtils.isEmpty(str)) {
            return defaultValueSupplier.get();
        }
        return str;
    }
    
    /**
     * 如果被检查对象为 {@code null} 或 "" 时，返回默认值（由 defaultValueSupplier 提供）；否则直接返回
     *
     * @param str                  被检查对象
     * @param defaultValueSupplier 默认值提供者
     * @param <T>                  对象类型（必须实现CharSequence接口）
     * @return 被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @throws NullPointerException {@code defaultValueSupplier == null} 时，抛出
     */
    public static <T extends CharSequence> T defaultIfEmpty(T str, Function<T, ? extends T> defaultValueSupplier) {
        if (StrUtils.isEmpty(str)) {
            return defaultValueSupplier.apply(null);
        }
        return str;
    }
    
    /**
     * 如果给定对象为{@code null}或者""或者空白符返回默认值
     *
     * <pre>
     * ObjectUtil.defaultIfBlank(null, null)      = null
     * ObjectUtil.defaultIfBlank(null, "")        = ""
     * ObjectUtil.defaultIfBlank("", "zz")      = "zz"
     * ObjectUtil.defaultIfBlank(" ", "zz")      = "zz"
     * ObjectUtil.defaultIfBlank("abc", *)        = "abc"
     * </pre>
     *
     * @param <T>          对象类型（必须实现CharSequence接口）
     * @param str          被检查对象，可能为{@code null}
     * @param defaultValue 被检查对象为{@code null}或者 ""或者空白符返回的默认值，可以为{@code null}或者 ""或者空白符
     * @return 被检查对象为{@code null}或者 ""或者空白符返回默认值，否则返回原值
     */
    public static <T extends CharSequence> T defaultIfBlank(final T str, final T defaultValue) {
        return StrUtils.isBlank(str) ? defaultValue : str;
    }
    
    /**
     * 如果被检查对象为 {@code null} 或 "" 或 空白字符串时，返回默认值（由 defaultValueSupplier 提供）；否则直接返回
     *
     * @param str                  被检查对象
     * @param defaultValueSupplier 默认值提供者
     * @param <T>                  对象类型（必须实现CharSequence接口）
     * @return 被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @throws NullPointerException {@code defaultValueSupplier == null} 时，抛出
     */
    public static <T extends CharSequence> T defaultIfBlank(T str, Supplier<? extends T> defaultValueSupplier) {
        if (StrUtils.isBlank(str)) {
            return defaultValueSupplier.get();
        }
        return str;
    }
    
    /**
     * 如果被检查对象为 {@code null} 或 "" 或 空白字符串时，返回默认值（由 defaultValueSupplier 提供）；否则直接返回
     *
     * @param str                  被检查对象
     * @param defaultValueSupplier 默认值提供者
     * @param <T>                  对象类型（必须实现CharSequence接口）
     * @return 被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @throws NullPointerException {@code defaultValueSupplier == null} 时，抛出
     */
    public static <T extends CharSequence> T defaultIfBlank(T str, Function<T, ? extends T> defaultValueSupplier) {
        if (StrUtils.isBlank(str)) {
            return defaultValueSupplier.apply(null);
        }
        return str;
    }
    
    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }
    
    /**************************************************************/
    // 拷贝属性方法
    /**************************************************************/
    
    /**
     * 浅拷贝属性,静态和临时两种属性不拷贝,父类的属性不拷贝
     *
     * @param src 原对象
     * @param dst 目标对象
     * @return 目标对象
     */
    public static <T> T copy(Object src, T dst) {
        Asserts.nonNull(src, _SRC_);
        Asserts.nonNull(dst, _DST_);
        if (src.getClass().isAssignableFrom(dst.getClass()) || dst.getClass().isAssignableFrom(src.getClass())) {
            // 如果是继承关系直接深度拷贝
            copyDeep(src, dst, null);
        }
        else {
            Field[] srcFields = Classes.getFields(src.getClass()).toArray(new Field[0]);
            copyFields(src, srcFields, dst, dst.getClass(), null);
        }
        return dst;
    }
    
    public static <T, S> T copy(S src, T dst, CopyPropFilter<S, T> filter) {
        Asserts.nonNull(src, _SRC_);
        Asserts.nonNull(dst, _DST_);
        
        
        if (src.getClass().isAssignableFrom(dst.getClass()) || dst.getClass().isAssignableFrom(src.getClass())) {
            // 如果是继承关系直接深度拷贝
            return copyDeep(src, dst, filter);
        }
        else {
            Field[] srcFields = Classes.getFields(src.getClass()).toArray(new Field[0]);
            copyFields(src, srcFields, dst, dst.getClass(), filter);
        }
        return dst;
    }
    
    /**
     * 对源和目标对象进行深度拷贝,静态和临时两种属性不拷贝
     *
     * @param src 原对象
     * @param dst 目标对象
     * @return 目标对象 dst
     */
    public static <T, S> T copyDeep(S src, T dst) {
        return copyDeep(src, dst, null);
    }
    
    /**
     * 对源和目标对象进行深度拷贝,静态和临时两种属性不拷贝
     *
     * @param src    原对象
     * @param dst    目标对象
     * @param filter 对象属性过滤器，返回 true 则表示复制该属性
     * @return 目标对象 dst
     */
    public static <T, S> T copyDeep(S src, T dst, CopyPropFilter<S, T> filter) {
        Asserts.nonNull(src, _SRC_);
        Asserts.nonNull(dst, _DST_);
        Class<?> aClass = src.getClass();
        Class<?> bClass = dst.getClass();
        boolean flag = false;
        if (aClass.isAssignableFrom(bClass)) {
            // 复制有限字段就行
            Field[] fields = Classes.getFields(src.getClass(), true).toArray(new Field[0]);
            for (Field field : fields) {
                Reflect.setAccessible(field);
                try {
                    Object val = field.get(src);
                    if (filter == null || filter.accept(src, field, val, dst)) {
                        Reflect.set(dst, field, val);
                    }
                }
                catch (Exception ignored) {}
            }
            
            flag = true;
        }
        else if (bClass.isAssignableFrom(aClass)) {
            Field[] fields = Classes.getFields(dst.getClass(), true).toArray(new Field[0]);
            for (Field field : fields) {
                try {
                    Reflect.setAccessible(field);
                    try {
                        Object val = field.get(src);
                        if (filter == null || filter.accept(src, field, val, dst)) {
                            Reflect.set(dst, field, val);
                        }
                    }
                    catch (Exception ignored) {}
                }
                catch (Exception ignored) {}
            }
            
            flag = true;
        }
        if (flag) {
            return dst;
        }
        
        // 非继承关系
        Class<?> superSrcClass = src.getClass();
        while (superSrcClass != null && superSrcClass != Object.class) {
            Class<?> superDestClass = dst.getClass();
            
            Field[] srcFields = Classes.getFields(src.getClass()).toArray(new Field[0]);
            while (superDestClass != null && superDestClass != Object.class) {
                copyFields(src, srcFields, dst, superDestClass, filter);
                superDestClass = superDestClass.getSuperclass();
            }
            
            superSrcClass = superSrcClass.getSuperclass();
        }
        return dst;
    }
    
    @FunctionalInterface
    public static interface CopyPropFilter<T, D> {
        /**
         * 返回 true 表示 复制 该参数
         *
         * @param src
         * @param field
         * @param value
         * @param d
         * @return 返回 true 表示 复制 该参数
         */
        boolean accept(T src, Field field, Object value, D d);
    }
    
    /**
     * 根据原类深属性拷贝(父类的循环查找拷贝),静态和临时两种属性不拷贝
     *
     * @param src 原对象
     * @param dst 目标对象
     * @return 目标对象
     */
    public static <T> T copySrcDeep(Object src, T dst) {
        Asserts.nonNull(src, _SRC_);
        Asserts.nonNull(dst, _DST_);
        Field[] srcFields = Classes.getFields(src.getClass(), true).toArray(new Field[0]);
        copyFields(src, srcFields, dst, dst.getClass(), null);
        return dst;
    }
    
    /**
     * 根据目标类深属性拷贝(父类的循环查找拷贝),静态和临时两种属性不拷贝
     *
     * @param src 原对象
     * @param dst 目标对象
     */
    public static <T> T copyDstDeep(Object src, T dst) {
        Asserts.nonNull(src, _SRC_);
        Asserts.nonNull(dst, _DST_);
        Field[] srcFields = Classes.getFields(src.getClass()).toArray(new Field[0]);
        copyFields(src, srcFields, dst, dst.getClass(), null);
        Class<?> superDestClass = dst.getClass().getSuperclass();
        while (superDestClass != null && superDestClass != Object.class) {
            copyFields(src, srcFields, dst, superDestClass, null);
            
            superDestClass = superDestClass.getSuperclass();
        }
        return dst;
    }
    
    /**
     * 当前对象内属性拷贝,静态和临时两种属性不拷贝
     *
     * @param src 原对象
     * @param dst 目标对象
     */
    private static <S, T> T copyFields(S src, Field[] sFields, T dst, Class<?> dClass, CopyPropFilter<S, T> filter) {
        try {
            
            Field[] dFields = dClass.getDeclaredFields();
            for (int i = 0; i < dFields.length; i++) {
                Field dField = dFields[i];
                int mod = dField.getModifiers();
                if (Modifier.isStatic(mod) || Modifier.isTransient(mod)) {
                    continue;// 静态和临时两种属性不拷贝
                }
                
                for (int j = 0; j < sFields.length; j++) {
                    Field sField = sFields[j];
                    int mod1 = sField.getModifiers();
                    if (Modifier.isStatic(mod1) || Modifier.isTransient(mod1)) {continue;}
                    
                    if (dField.getName().equals(sField.getName())) {
                        Class<?> fc_src = sField.getType();
                        Class<?> fc_dist = dField.getType();
                        if (fc_src == fc_dist || dField.getType().isAssignableFrom(sField.getType())) {
                            // 类型兼容才能拷贝
                            Reflect.setAccessible(sField);
                            Object value = sField.get(src);
                            try {
                                Object val = sField.get(src);
                                if (filter == null || filter.accept(src, sField, val, dst)) {
                                    Reflect.setAccessible(dField);
                                    Reflect.set(dst, dField, value);
                                    
                                }
                            }
                            catch (Exception ignored) {}
                            break;
                        }
                    }
                }
            }
        }
        catch (Exception e) {
            // 异常不处理
            if (Systems.isDebug()) {
                e.printStackTrace();
            }
        }
        
        return dst;
    }
    
    
    public static <T> T requireNonNull(T obj) {
        if (obj == null) {throw new NullPointerException();}
        return obj;
    }
    
    public static <T> T requireNonNull(T obj, String message) {
        if (obj == null) {throw new NullPointerException(message);}
        return obj;
    }
    
    public static boolean isNull(Object obj) {
        return obj == null;
    }
    
    
    public static boolean nonNull(Object obj) {
        return obj != null;
    }
    
    public static <T> int compare(T a, T b, Comparator<? super T> c) {
        return (a == b) ? 0 : c.compare(a, b);
    }
    
    
    // 使用Fisher–Yates洗牌算法，以线性时间复杂度打乱数组顺序
    
    /**
     * 打乱数组顺序，会变更原数组
     *
     * @param <T>   元素类型
     * @param array 数组，会变更
     * @return 打乱后的数组
     */
    public static <T> T[] shuffle(T[] array) {
        return shuffle(array, Randoms.getRandom());
    }
    
    /**
     * 打乱数组顺序，会变更原数组
     *
     * @param <T>    元素类型
     * @param array  数组，会变更
     * @param random 随机数生成器
     * @return 打乱后的数组
     */
    public static <T> T[] shuffle(T[] array, Random random) {
        if (array == null || random == null || array.length <= 1) {
            return array;
        }
        
        for (int i = array.length; i > 1; i--) {
            swap(array, i - 1, random.nextInt(i));
        }
        
        return array;
    }
    
    /**
     * 交换数组中两个位置的值
     *
     * @param <T>    元素类型
     * @param array  数组
     * @param index1 位置1
     * @param index2 位置2
     * @return 交换后的数组，与传入数组为同一对象
     */
    public static <T> T[] swap(T[] array, int index1, int index2) {
        if (isEmpty(array)) {
            throw new IllegalArgumentException("Array must not empty !");
        }
        T tmp = array[index1];
        array[index1] = array[index2];
        array[index2] = tmp;
        return array;
    }
    
    /**
     * 交换数组中两个位置的值
     *
     * @param array  数组对象
     * @param index1 位置1
     * @param index2 位置2
     * @return 交换后的数组，与传入数组为同一对象
     */
    public static Object swap(Object array, int index1, int index2) {
        if (isEmpty(array)) {
            throw new IllegalArgumentException("Array must not empty !");
        }
        Object tmp = get(array, index1);
        Array.set(array, index1, Array.get(array, index2));
        Array.set(array, index2, tmp);
        return array;
    }
    
    
    /**
     * 打乱List顺序，会变更原数组
     *
     * @param <T>   元素类型
     * @param array 数组，会变更
     * @return 打乱后的数组
     */
    public static <T> List<T> shuffle(List<T> array) {
        return shuffle(array, Randoms.getRandom());
    }
    
    /**
     * 打乱List顺序，会变更原数组
     *
     * @param <T>    元素类型
     * @param array  数组，会变更
     * @param random 随机数生成器
     * @return 打乱后的数组
     */
    public static <T> List<T> shuffle(List<T> array, Random random) {
        if (array == null || random == null || array.size() <= 1) {
            return array;
        }
        
        for (int i = array.size(); i > 1; i--) {
            swap(array, i - 1, random.nextInt(i));
        }
        
        return array;
    }
    
    /**
     * 交换list中两个位置的值
     *
     * @param <T>    元素类型
     * @param array  数组
     * @param index1 位置1
     * @param index2 位置2
     * @return 交换后的数组，与传入数组为同一对象
     */
    public static <T> List<T> swap(List<T> array, int index1, int index2) {
        if (array == null || array.isEmpty()) {
            throw new IllegalArgumentException("List must not empty !");
        }
        T tmp = array.get(index1);
        array.set(index1, array.get(index2));
        array.set(index2, tmp);
        return array;
    }
    
    /**
     * 强转int型
     *
     * @param val     输入值
     * @param throwEx 转换失败 是否抛异常
     * @return
     * @throws NumberFormatException
     */
    public final static int toInt(Object val, boolean throwEx) throws NumberFormatException {
        if (val == null) return 0;
        if (val instanceof Number) return ((Number) val).intValue();
        if (val instanceof Boolean) return (Boolean) val ? 1 : 0;
        if (val instanceof Character) return (Character) val;
        if (val instanceof CharSequence) return Integer.parseInt(val.toString());
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get() ? 1 : 0;
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to int");}
        return 0;
    }
    
    /**
     * 强转long型
     *
     * @param val     输入值
     * @param throwEx 转换失败 是否抛异常
     * @return
     * @throws NumberFormatException
     */
    public final static long toLong(Object val, boolean throwEx) throws NumberFormatException {
        if (val == null) return 0L;
        if (val instanceof Number) return ((Number) val).longValue();
        if (val instanceof Boolean) return (Boolean) val ? 1L : 0L;
        if (val instanceof Character) return (Character) val;
        if (val instanceof CharSequence) return Long.parseLong(val.toString());
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get() ? 1L : 0L;
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to long");}
        return 0L;
    }
    
    /**
     * 强转double型
     *
     * @param val     输入值
     * @param throwEx 转换失败 是否抛异常
     * @return
     * @throws NumberFormatException
     */
    public final static double toDouble(Object val, boolean throwEx) throws NumberFormatException {
        if (val == null) return 0.0;
        if (val instanceof Number) return ((Number) val).doubleValue();
        if (val instanceof Boolean) return (Boolean) val ? 1.0 : 0.0;
        if (val instanceof Character) return (Character) val;
        if (val instanceof CharSequence) return Double.parseDouble(val.toString());
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get() ? 1.0 : 0;
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to double");}
        return 0.0;
    }
    
    /**
     * 强转float型
     *
     * @param val
     * @param throwEx
     * @return
     * @throws NumberFormatException
     */
    public final static float toFloat(Object val, boolean throwEx) throws NumberFormatException {
        if (val == null) return 0f;
        if (val instanceof Number) return ((Number) val).floatValue();
        if (val instanceof Boolean) return (Boolean) val ? 1f : 0f;
        if (val instanceof Character) return (Character) val;
        if (val instanceof CharSequence) return Float.parseFloat(val.toString());
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get() ? 1f : 0;
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to float");}
        return 0f;
    }
    
    /**
     * 强转short型
     *
     * @param val     输入值
     * @param throwEx 转换失败 是否抛异常
     * @return
     * @throws NumberFormatException
     */
    public final static short toShort(Object val, boolean throwEx) throws NumberFormatException {
        if (val == null) return 0;
        if (val instanceof Number) return ((Number) val).shortValue();
        if (val instanceof Boolean) return (Boolean) val ? (short) 1 : 0;
        if (val instanceof Character) return (short) (char) val;
        if (val instanceof CharSequence) return (short) Double.parseDouble(val.toString());
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get() ? (short) 1 : 0;
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to short");}
        return 0;
    }
    
    /**
     * 强转byte型
     *
     * @param val     输入值
     * @param throwEx 转换失败 是否抛异常
     * @return
     * @throws NumberFormatException
     */
    public final static byte toByte(Object val, boolean throwEx) throws NumberFormatException {
        if (val == null) return 0;
        if (val instanceof Number) return ((Number) val).byteValue();
        if (val instanceof Boolean) return (Boolean) val ? (byte) 1 : 0;
        if (val instanceof Character) return (byte) (char) val;
        if (val instanceof CharSequence) return (byte) Double.parseDouble(val.toString());
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get() ? (byte) 1 : 0;
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to byte");}
        return 0;
    }
    
    /**
     * 强转char型
     *
     * @param val     输入值
     * @param throwEx 转换失败 是否抛异常
     * @return char
     * @throws IllegalArgumentException
     */
    public final static char toChar(Object val, boolean throwEx) throws IllegalArgumentException {
        if (val == null) return 0;
        if (val instanceof Character) return (Character) val;
        if (val instanceof Number) return (char) ((Number) val).shortValue();
        if (val instanceof Boolean) return (Boolean) val ? (char) 1 : 0;
        if (val instanceof CharSequence) return ((CharSequence) val).length() > 0 ? ((CharSequence) val).charAt(0) : 0;
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get() ? (char) 1 : 0;
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to byte");}
        return 0;
    }
    
    /**
     * 转为boolean 支持 "1", "true", "yes", "YES", "on", "ON", "Y", "y" "是"
     *
     * @param val     输入值
     * @param throwEx 转换失败 是否抛异常
     * @return
     * @throws IllegalArgumentException
     */
    public final static boolean toBoolean(Object val, boolean throwEx) throws IllegalArgumentException {
        if (val == null) return false;
        if (val instanceof Boolean) return (Boolean) val;
        if (val instanceof Number) return ((Number) val).intValue() != 0;
        if (val instanceof Character) {
            char c = (char) val;
            switch (c) {
                case 0x0001:
                case '1':
                case 'Y':
                case 'y':
                case '是':
                    return true;
                default:
                    return false;
            }
        }
        ;
        if (val instanceof CharSequence) {
            String s = val.toString();
            switch (s) {
                case "true":
                case "1":
                case "yes":
                case "YES":
                case "ON":
                case "on":
                case "Y":
                case "y":
                case "是":
                    return true;
                default:
                    return false;
            }
        }
        if (val instanceof AtomicBoolean) return ((AtomicBoolean) val).get();
        if (throwEx) {throw new IllegalArgumentException("Cannot convert " + val.getClass() + " to boolean");}
        return false;
    }
}
